home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d939.lha / ExtraCmds / source_etc.lha / src / Tee.c < prev    next >
C/C++ Source or Header  |  1993-10-22  |  4KB  |  146 lines

  1. /*
  2.  *  Tee - Join pipes and make copies of input.
  3.  *  Copyright (C) 1989, 1992, 1993 Torsten Poulin
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; if not, write to the Free Software
  17.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  The author can be contacted by s-mail at
  20.  *    Torsten Poulin
  21.  *    Banebrinken 99, 2, 77
  22.  *    DK-2400 Copenhagen NV
  23.  *    DENMARK
  24.  *
  25.  * $Id: Tee.c,v 37.5 93/06/21 18:13:15 Torsten Rel $
  26.  * $Log:    Tee.c,v $
  27.  * Revision 37.5  93/06/21  18:13:15  Torsten
  28.  * Throughput increased by the addition of a 16k buffer.
  29.  * Tee no longer complains when it cannot open a specified
  30.  * output file (the message was swallowed by the pipe under
  31.  * WShell).
  32.  * 
  33.  * Revision 37.4  93/02/13  16:44:20  Torsten
  34.  * Forgot the initial '$' in the copyright tag.
  35.  * 
  36.  * Revision 37.3  93/02/13  16:36:57  Torsten
  37.  * Replaced exec.library/SetSignal() with dos.library/CheckSignal().
  38.  * Removed IGNORE switch because it seemed pretty silly.
  39.  * 
  40.  */
  41.  
  42. #include <exec/types.h>
  43. #include <exec/memory.h>
  44. #include <dos/dos.h>
  45. #include <proto/exec.h>
  46. #include <proto/dos.h>
  47. #include <proto/intuition.h>
  48. #include "tee_rev.h"
  49.  
  50. #define OPT_TO      0
  51. #define OPT_APPEND  1
  52. #define BUFLEN 16384L
  53.  
  54. char const versionID[] = VERSTAG;
  55. char const copyright[] = "$COPYRIGHT:© 1989,1992,1993 Torsten Poulin$";
  56.  
  57. struct fileList {
  58.   struct fileList *next;
  59.   BPTR file;
  60. };
  61.  
  62. LONG entrypoint(VOID)
  63. {
  64.   struct RDArgs        *args;
  65.   struct DosLibrary    *DOSBase;
  66.   struct fileList *list, *p;
  67.   BPTR *buffer;
  68.   BPTR in, out;
  69.   LONG rlen;
  70.   LONG arg[2];
  71.   LONG rc = RETURN_OK;
  72.  
  73.   if (!(DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 37L)))
  74.     return RETURN_FAIL;
  75.  
  76.   arg[OPT_TO] = arg[OPT_APPEND] = 0L;
  77.   in = Input();
  78.   out = Output();
  79.  
  80.   if (!(buffer = AllocVec(BUFLEN, MEMF_ANY))) {
  81.     PrintFault(ERROR_NO_FREE_STORE, "Tee");
  82.     rc = RETURN_FAIL;
  83.   }
  84.   else {
  85.     if (args = ReadArgs("TO/M,APPEND/S", arg, NULL)) {
  86.       if (arg[OPT_TO]) {
  87.     UBYTE **name;
  88.     struct fileList *newnode;
  89.     LONG mode;
  90.     BPTR file;
  91.             
  92.     mode = arg[OPT_APPEND] ? MODE_READWRITE : MODE_NEWFILE;
  93.             
  94.     list = NULL;
  95.     /* Open the files */
  96.     for (name = (UBYTE **) arg[OPT_TO]; *name; name++) {
  97.       if (!(file = Open(*name, mode)))
  98.         continue;
  99.       if (arg[OPT_APPEND])
  100.         Seek(file, 0L, OFFSET_END);
  101.  
  102.       /* Store the filehandle */
  103.       if (!(newnode = AllocVec(sizeof(struct fileList), MEMF_ANY))) {
  104.         PrintFault(ERROR_NO_FREE_STORE, "Tee");
  105.         rc = RETURN_FAIL;
  106.         goto bail_out;
  107.       }
  108.       newnode->file = file;
  109.       newnode->next = list;
  110.       list = newnode;
  111.     }
  112.       }
  113.  
  114.       /* Do the copying ... */
  115.       while ((rlen = Read(in, buffer, BUFLEN)) > 0) {
  116.     if (CheckSignal(SIGBREAKF_CTRL_C)) {
  117.       rc = RETURN_WARN;
  118.       break;
  119.     }
  120.     Write(out, buffer, rlen);
  121.     for (p = list; p; p = p->next)
  122.       Write(p->file, buffer, rlen);
  123.       }
  124.     bail_out:       
  125.       /* Close the files and free up memory*/
  126.       for (p = list; p; ) {
  127.     struct fileList *remember;
  128.                 
  129.     remember = p;
  130.     Close(p->file);
  131.     p = p->next;
  132.     FreeVec(remember);
  133.       }
  134.       FreeArgs(args);
  135.     }
  136.     else {
  137.       LONG err = IoErr();
  138.       PrintFault(err, "Tee");
  139.       rc = RETURN_ERROR;
  140.     }
  141.     FreeVec(buffer);
  142.   }
  143.   CloseLibrary((struct Library *) DOSBase);
  144.   return rc;
  145. }
  146.